package com.ruoyi.project.system.service.impl;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.system.domain.SmExtract;
import com.ruoyi.project.system.domain.SmIncome;
import com.ruoyi.project.system.domain.SmPay;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.domain.vo.CashOut;
import com.ruoyi.project.system.mapper.*;
import com.ruoyi.project.system.service.ISmIncomeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.uuid.Seq.getExtractId;
import static com.ruoyi.framework.web.domain.AjaxResult.error;
import static com.ruoyi.framework.web.domain.AjaxResult.success;

/**
 * 收入Service业务层处理
 */
@Service
public class SmIncomeServiceImpl implements ISmIncomeService {
    @Autowired
    private SmIncomeMapper smIncomeMapper;

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SmExtractMapper smExtractMapper;

    @Autowired
    private SmPayMapper smPayMapper;

    @Override
    public Map<String, Object> index() {
        Map<String, Object> result = new HashMap<>();
        result.put("ranking", smIncomeMapper.ranking());
        result.put("todayTotal", smPayMapper.todayTotal() + 1000);
        return result;
    }

    @Override
    public AjaxResult cashOutAndRefund(Long userId) {
        AjaxResult result = new AjaxResult();
        List<CashOut> cashOuts = smIncomeMapper.cashOutList(userId);
        List<SmIncome> untreatedRefunds = smIncomeMapper.untreatedRefundList(userId);
        BigDecimal cashOutTotal = new BigDecimal(0);
        for (CashOut cashOut : cashOuts) {
            cashOutTotal = cashOutTotal.add(cashOut.getAmount());
        }
        BigDecimal untreatedRefundTotal = new BigDecimal(0);
        for (SmIncome untreatedRefund : untreatedRefunds) {
            untreatedRefundTotal = untreatedRefundTotal.add(untreatedRefund.getAmount());
        }
        result.put("cashOuts", cashOuts);
        result.put("untreatedRefunds", untreatedRefunds);
        result.put("cashOutTotal", cashOutTotal);
        result.put("untreatedRefundTotal", untreatedRefundTotal);
        result.put("actualTotal", cashOutTotal.subtract(untreatedRefundTotal));
        return result;
    }

    @Override
    @Transactional
    public AjaxResult carryOnCashOut(Long userId) {
        List<CashOut> cashOuts = smIncomeMapper.cashOutList(userId);
        List<SmIncome> untreatedRefunds = smIncomeMapper.untreatedRefundList(userId);
        BigDecimal cashOutTotal = new BigDecimal(0);
        for (CashOut cashOut : cashOuts) {
            cashOutTotal = cashOutTotal.add(cashOut.getAmount());
        }
        BigDecimal untreatedRefundTotal = new BigDecimal(0);
        for (SmIncome untreatedRefund : untreatedRefunds) {
            untreatedRefundTotal = untreatedRefundTotal.add(untreatedRefund.getAmount());
        }
        if (cashOutTotal.compareTo(untreatedRefundTotal) < 0) {
            return error("余额不足");
        }
        String extractId = getExtractId();

        List<Integer> cashOutIds = cashOuts.stream().map(CashOut::getId).collect(Collectors.toList());
        smIncomeMapper.cashOutSetIncome(cashOutIds, "2", "4", extractId);

        if (untreatedRefunds != null && !untreatedRefunds.isEmpty()) {
            List<Integer> untreatedRefundsIds = untreatedRefunds.stream().map(SmIncome::getId).collect(Collectors.toList());
            smIncomeMapper.cashOutSetIncome(untreatedRefundsIds, "5", "6", extractId);
        }
        // 添加提现单
        SysUser sysUser = userMapper.selectUserById(userId);
        BigDecimal actualTotal = cashOutTotal.subtract(untreatedRefundTotal);
        SmExtract smExtract = new SmExtract(extractId, userId.intValue(), sysUser.getAlipayName(), sysUser.getAlipayAccount(), actualTotal);
        boolean isTx = "2".equals(sysUser.getEnableTansferAccounts()) && actualTotal.compareTo(sysUser.getMaxTansferAccounts()) == -1;
        if (isTx) {                         // 自动转账
            smExtract.setStatus("未转账");
            smExtractMapper.insertSmExtract(smExtract);
            // 启用异步转账
            AsyncManager.me().execute(AsyncFactory.zhuanZhang(smExtract)); // MGZ TODO 2025/4/15:异步转账
            return success("操作成功，立即到账！");
        } else {
            smExtractMapper.insertSmExtract(smExtract);
            return success("操作成功，等待审核！");
        }
    }

    @Override
    public void inComeRefund(SmPay smPay) {
        List<SmIncome> smIncomeList = smIncomeMapper.selectSmIncomeList(new SmIncome(smPay.getOrderNo()));
        for (SmIncome smIncome : smIncomeList) {
            if ("2".equals(smIncome.getStatus())) {         // 已入账
                smIncomeMapper.refundSetIncome(smIncome.getId(), "2", "3");
            } else if ("4".equals(smIncome.getStatus())) {  // 已提现
                smIncomeMapper.refundSetIncome(smIncome.getId(), "4", "5");
            }
        }
    }


    /**
     * 查询收入
     *
     * @param id 收入主键
     * @return 收入
     */
    @Override
    public SmIncome selectSmIncomeById(Integer id) {
        return smIncomeMapper.selectSmIncomeById(id);
    }

    /**
     * 查询收入列表
     *
     * @param smIncome 收入
     * @return 收入
     */
    @Override
    public List<SmIncome> selectSmIncomeList(SmIncome smIncome) {
        return smIncomeMapper.selectSmIncomeList(smIncome);
    }

    /**
     * 新增收入
     *
     * @param smIncome 收入
     * @return 结果
     */
    @Override
    public int insertSmIncome(SmIncome smIncome) {
        smIncome.setCreateTime(DateUtils.getNowDate());
        return smIncomeMapper.insertSmIncome(smIncome);
    }

    /**
     * 修改收入
     *
     * @param smIncome 收入
     * @return 结果
     */
    @Override
    public int updateSmIncome(SmIncome smIncome) {
        smIncome.setUpdateTime(DateUtils.getNowDate());
        return smIncomeMapper.updateSmIncome(smIncome);
    }

}
